/**
 *                            License
 * THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS  
 * CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). 
 * THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.  
 * ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR  
 * COPYRIGHT LAW IS PROHIBITED.
 * 
 * BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND  
 * AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE  
 * MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED 
 * HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
 * 
 */
package com.lineage.server.model.Instance;

import com.lineage.server.GeneralThreadPool;
import com.lineage.server.IdFactory;
import com.lineage.server.codes.ActionCodes;
import com.lineage.server.datatables.SprTable;
import com.lineage.server.model.L1World;
import com.lineage.server.packetserver.S_DoActionGFX;
import com.lineage.server.packetserver.S_DollPack;
import com.lineage.server.packetserver.S_OwnCharStatus;
import com.lineage.server.packetserver.S_SkillIconGFX;
import com.lineage.server.packetserver.S_SkillSound;
import com.lineage.server.templates.L1MagicDoll;
import com.lineage.server.templates.L1Npc;
import com.lineage.server.utils.Random;

/**
 * 魔法娃娃控制项.
 */
public class L1DollInstance extends L1NpcInstance {

    // 时间计测用
    /**
     * 娃娃计时器.
     */
    class DollTimer implements Runnable {
        @Override
        public void run() {
            if (L1DollInstance.this._destroyed) { // 检查是否已经被抛弃
                return;
            }
            L1DollInstance.this.deleteDoll(); // 删除娃娃
        }
    }

    /** 序列版本UID. */
    private static final long serialVersionUID = 1L;
    /** 召唤后可持有的时间. */
    public static final int DOLL_TIME = 1800000;
    /** 道具编号. */
    private int itemId;
    /** 道具的OBJID. */
    private int itemObjId;
    /** 表情动作执行几率. */
    private int run;
    /** 娃娃的面向(下方). */
    private static final int DOLL_HEADING = 5;
    /** 是否删除. */
    private boolean isDelete = false;

    /**
     * 魔法娃娃控制项.
     * 
     * @param template
     *            资料
     * @param master
     *            主人
     * @param item
     *            道具编号
     * @param itemObj
     *            道具的OBJID
     */
    public L1DollInstance(final L1Npc template, final L1PcInstance master,
            final int item, final int itemObj) {

        super(template); // 载入资料
        this.setId(IdFactory.getInstance().nextId()); // 设定对象在世界中唯一的ID
        this.setItemId(item); // 设置道具编号
        this.setItemObjId(itemObj); // 设置道具的OBJID
        GeneralThreadPool.getInstance().schedule(new DollTimer(), DOLL_TIME);
        this.setMaster(master); // 设置主人
        final int random = Random.nextInt(5) - 2; // 娃娃的随机坐标
        this.setX(master.getX() + random); // X坐标
        this.setY(master.getY() + random); // Y坐标
        this.setMap(master.getMapId()); // 地图编号
        this.setHeading(DOLL_HEADING); // 面向(下方)
        this.setLightSize(template.getLightSize()); // 照明范围
        this.setMoveSpeed(1); // 一段加速
        this.setBraveSpeed(1); // 二段加速
        L1World.getInstance().storeObject(this); // 储存对象
        L1World.getInstance().addVisibleObject(this); // 增加可见对象
        for (final L1PcInstance pc : L1World.getInstance().getRecognizePlayer(
                this)) {
            this.onPerceive(pc); // 认识范围内进入玩家
        }
        master.addDoll(this); // 添加到doll列表
        if (!this.isAiRunning()) {
            this.startAI(); // 开始AI
        }
        if (L1MagicDoll.isHpRegeneration(this._master)) {
            master.startHpRegenerationByDoll(); // 开始回血
        }
        if (L1MagicDoll.isMpRegeneration(this._master)) {
            master.startMpRegenerationByDoll(); // 开始回魔
        }
        if (L1MagicDoll.isItemMake(this._master)) {
            master.startItemMakeByDoll(); // 开始获得道具
        }
    }

    /**
     * 删除魔法娃娃.
     */
    public final void deleteDoll() {
        this.broadcastPacket(new S_SkillSound(this.getId(), 5936));
        if ((this._master != null) && this.isDelete) {
            final L1PcInstance pc = (L1PcInstance) this._master;
            pc.sendPackets(new S_SkillIconGFX(56, 0));
            pc.sendPackets(new S_OwnCharStatus(pc));
        }

        if (this._master != null) {
            if (L1MagicDoll.isHpRegeneration(this._master)) {
                ((L1PcInstance) this._master).stopHpRegenerationByDoll();
            }
            if (L1MagicDoll.isMpRegeneration(this._master)) {
                ((L1PcInstance) this._master).stopMpRegenerationByDoll();
            }
            if (L1MagicDoll.isItemMake(this._master)) {
                ((L1PcInstance) this._master).stopItemMakeByDoll();
            }

            this._master.getDollList().remove(this.getId());
        }
        this.deleteMe();
    }

    /**
     * 魔法娃娃表情动作.
     */
    private void dollAction() {
        this.run = Random.nextInt(100) + 1;
        if (this.run <= 10) {
            int actionCode = ActionCodes.ACTION_AGGRESS; // 67(挑衅动作 Alt+3)
            if (this.run <= 5) {
                actionCode = ActionCodes.ACTION_THINK; // 66(思考动作 Alt+4)
            }

            this.broadcastPacket(new S_DoActionGFX(this.getId(), actionCode));
            final int sleepTime = SprTable.getInstance().getSprSpeed(
                    this.getTempCharGfx(), actionCode);
            this.setSleepTime(this.calcSleepTime(sleepTime, MOVE_SPEED)); // 休眠
        }
    }

    /**
     * 取得道具编号.
     * 
     * @return 道具编号
     */
    public final int getItemId() {
        return this.itemId;
    }

    /**
     * 取得道具的OBJID.
     * 
     * @return 道具的OBJID
     */
    public final int getItemObjId() {
        return this.itemObjId;
    }

    // 如果没有目标处理
    @Override
    public final boolean noTarget() {
        if ((this._master != null) && !this._master.isDead()
                && (this._master.getMapId() == this.getMapId())) {
            if (this.getLocation().getTileLineDistance(
                    this._master.getLocation()) > 2) {
                final int dir = this.moveDirection(this._master.getX(),
                        this._master.getY());
                this.setDirectionMove(dir);
                this.setSleepTime(this.calcSleepTime(this.getPassispeed(),
                        MOVE_SPEED));
            } else {
                // 魔法娃娃 - 特殊动作
                this.dollAction();
            }
        } else {
            this.isDelete = true;
            this.deleteDoll();
            return true;
        }
        return false;
    }

    @Override
    public void onGetItem(final L1ItemInstance item) {
    }

    @Override
    public void onItemUse() {
    }

    // 对象的荧幕范围进入玩家
    @Override
    public final void onPerceive(final L1PcInstance perceivedFrom) {
        // 判断旅馆内是否使用相同钥匙
        final int mapId = perceivedFrom.getMapId(); // 角色所在的地图编号
        final int innKeyId = perceivedFrom.getInnKeyId(); // 角色的旅馆钥匙编号
        if ((mapId >= 16384) && (mapId <= 25088)
                && (innKeyId != this._master.getInnKeyId())) {
            return;
        }
        perceivedFrom.addKnownObject(this);
        perceivedFrom.sendPackets(new S_DollPack(this));
    }

    /**
     * 设置道具编号.
     * 
     * @param i
     *            道具编号
     */
    public final void setItemId(final int i) {
        this.itemId = i;
    }

    /**
     * 设置道具的OBJID.
     * 
     * @param i
     *            道具的OBJID
     */
    public final void setItemObjId(final int i) {
        this.itemObjId = i;
    }
}
